home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / utility.arc / UTILITY.INC next >
Text File  |  1985-02-10  |  12KB  |  390 lines

  1. {Utility.Inc}
  2.  
  3. { This utility include file includes the utility files printed in PC TECH
  4.   JOURNAL, Feb. 1985.  For a complete write up of this procedures, read the
  5.   article that accompanied them. }
  6.  
  7. (*************************************************************************)
  8.  
  9. { Turbo Pascal procedure to retrieve command line parameters }
  10. { Copyritght 1984 Michael A. Covengton }
  11.  
  12. Type Parmtype = string[127];
  13.  
  14. procedure getparm(Var s:parmtype);
  15.  
  16.   { Returns first available parameter from DOS command }
  17.   { line and removes it so next parameter will be      }
  18.   { returned on next call.  If no more parameters are  }
  19.   { avaiable, returns a null string.                   }
  20.  
  21. var parms : parmtype absolute CSEG:$80;
  22. begin
  23.   s := '';
  24.   { parms[1] exists enen when length is zero }
  25.   while (Length(Parms) > 0) and (parms[1] = ' ') do
  26.     delete(Parms,1,1);
  27.   While (length(parms) > 0) and (parms[1] <> ' ') do
  28.     begin
  29.       s := s + parms[1]; delete(parms,1,1);
  30.     End
  31. end;
  32.  
  33. (*************************************************************************)
  34.  
  35. { Turbo Pascal routines to read and set date and time }
  36. { copyright 1984 Michael A. Covington }
  37.  
  38. { Each routine requires the following type definitions }
  39. { but does not require the other routines.             }
  40.  
  41. type datetimetype = string[8];
  42.      regtype     = record
  43.                      ax,bx,cx,dx,bp,si,di,ds,es,flags : integer;
  44.                    end;
  45.  
  46. function date : datetimetype;
  47.   { returns current date in form '08/31/84'.}
  48. var reg     : regtype;
  49.     y,m,d,w : datetimetype;
  50.     i       : integer;
  51. begin
  52.   reg.ax := $2A00;
  53.   intr($21,reg);
  54.   str(reg.cx:4,y);
  55.   delete(y,1,2);
  56.   str(hi(reg.dx):2,m);
  57.   str(lo(reg.dx):2,d);
  58.   w := m +'/' + d + '/' + y;
  59.   for i := 1 to length(w) do if w[i]=' ' then w[i] := '0';
  60.   date := w;
  61. end;
  62.  
  63. function time : datetimetype;
  64.   { return current time in form '08:13:59'.}
  65. var reg     : regtype;
  66.     h,m,s,w : datetimetype;
  67.     i       : integer;
  68. begin
  69.   reg.ax := $2C00;
  70.   intr($21,reg);
  71.   str(hi(reg.cx):2,h);
  72.   str(lo(reg.cx):2,m);
  73.   str(hi(reg.dx):2,s);
  74.   w := h + ':' + m + ':' + s;
  75.   for i := 1 to length(w) do if w[i] = ' ' then w[i] := '0';
  76.   time := w;
  77. end;
  78.  
  79. procedure setdate(x:datetimetype);
  80.   { set date.  accepts string in fromat '08/31/84'.}
  81. var reg            : regtype;
  82.     rh,rl,c1,c2,c3 : integer;
  83. begin
  84.   reg.ax := $2B00;
  85.   val(x[1]+x[2],rh,c1);     {month goes in DH}
  86.   val(x[4]+x[5],rl,c2);     {day goes in DL  }
  87.   reg.dx := rh * 256 + rl;
  88.   val(x[7]+x[8],rl,c3);     {year goes ni CX }
  89.   reg.cx := rl + 1900;
  90.   if rl < 80 then reg.cx := reg.cx + 100;  {21st century}
  91.   c1 := c1 + c2 + c3;       {return codes for val}
  92.   if c1 = 0 then intr($21,reg);
  93.   if c1+lo(reg.ax) <> 0 then
  94.     begin
  95.       writeln;
  96.       writeln('Error -- invalid date, ''',x,'''');
  97.       halt;
  98.     end;
  99. end;
  100.  
  101. procedure settime(x:datetimetype);
  102.   { set time  accepts string in format '08:13:59'.}
  103. var reg            : regtype;
  104.     rh,rl,c1,c2,c3 : integer;
  105. begin
  106.   reg.ax := $2D00;
  107.   val(x[1]+x[2],rh,c1);       {hours go in CH  }
  108.   val(x[4]+x[5],rl,c2);       {minutes go in CL}
  109.   reg.cx := rh * 256 + rl;
  110.   val(x[7]+x[8],rh,c3);       {seconds go in DH}
  111.   reg.dx := rh*256;
  112.   c1 := c1 + c2 + c3;         {return codes for val}
  113.   if c1 = 0 then intr($21,reg);
  114.   if c1+lo(reg.ax) <> 0 then
  115.     begin
  116.       writeln;
  117.       writeln('Error -- invalid time, ''',x,'''');
  118.       halt;
  119.     end;
  120. end;
  121.  
  122. (*************************************************************************)
  123.  
  124. { Turbo Pascal routines for tree-structured directories }
  125. { copyright 1984 Michael a. Covinton }
  126.  
  127. { requires MS-DOs or PC-DOS 2.0 or higher, execpt as noted }
  128.  
  129. { All the rouintes require these type defintions.          }
  130. { However, except as noted, they do not require each other.}
  131.  
  132. type pathtype  = string[63];
  133.      drivetype = string[2];
  134. {instead of the rtype in TECH JOURNAL the regtype defined earlier will be used}
  135.  
  136. procedure xxdiskerr(x:drivetype);
  137. begin
  138.   writeln('Error -- invalid disk drive, ''',x,'''');
  139.   halt;
  140. end;
  141.  
  142. procedure xxpatherr(x:pathtype);
  143. begin
  144.   writeln('Error -- invalid path, ''',x,'''');
  145.   halt;
  146. end;
  147.  
  148. function currentdrive : drivetype;
  149.   { returns designator for current default drive, e.g., 'A:'.}
  150.   { works under DOS version 1.}
  151. var w   : drivetype;
  152.     reg : regtype;   {note earlier change in rtype name}
  153. begin
  154.   reg.ax := $1900;
  155.   intr($21,reg);
  156.   w := 'A:';
  157.   w[1] := chr(ord(w[1])+lo(reg.ax));
  158.   currentdrive := w;
  159. end;
  160.  
  161. procedure chdrive(x:drivetype);
  162.   { chooses a new default drive.                          }
  163.   { parameter can have the form 'A:', 'A', 'a:', or 'a'.  }
  164.   { works under DOS version 1.  requires xxdiskerr, above }
  165. var reg : regtype;  {note earlier change in rtype name}
  166. begin
  167.   reg.ax := $0E00;
  168.   reg.dx := ord(upcase(x[1])) - ord('A');
  169.   intr($21,reg);
  170.   if (reg.dx < 0) or (lo(reg.ax) < lo(reg.dx)) then xxdiskerr(x);
  171. end;
  172.  
  173. function diskspace(x:drivetype) : real;
  174.   { returns number of bytes available on specified disk.  }
  175.   { parameter as for chdrive.  requires xxdiskerr, above  }
  176. var reg : regtype;  {note earlier change in rtype name}
  177. begin
  178.   reg.ax := $3600;
  179.   reg.dx := 1 + ord(upcase(x[1])) - ord('A');
  180.   intr($21,reg);
  181.   if reg.ax = $FFFF then
  182.     xxdiskerr(x)
  183.   else
  184.     diskspace := ( 256.0 * hi(reg.dx) + ln(reg.dx) ) * reg.ax * reg.cx;
  185. end;
  186.  
  187. function currentdir(x:drivetype) : pathtype;
  188.   { returns full path to active directory on specified drive. }
  189.   { including backslash at beginning, not including drive     }
  190.   { designator.  Parameter as for chdrive.                    }
  191.   { requires xxdiskerr, above                                 }
  192. var w   : pathtype;
  193.     reg : regtype;    {note earlier change in rtype name}
  194.     i   : integer;
  195. begin
  196.   { get current path }
  197.   reg.ax := $4700;
  198.   reg.dx := 1 + ord(upcase(x[1])) - ord('A');
  199.   reg.ds := seg(w[1]);
  200.   reg.si := ofs(w[1]);
  201.   intr($21,reg);
  202.   if (reg.flags and 1) > 0 then xxdiskerr(x);
  203.   { turn it into a Turob string }
  204.   I := 1;
  205.   while w[i] <> chr(0) do i := i + 1;
  206.   w[0] := chr(i-1);
  207.   for i := 1 to length(w) do w[i] := upcase(w[i]);
  208.   currentdir := '\' + w;
  209. end;
  210.  
  211. procedure xxdir(x:pathtype; k:integer);
  212.   { executes crdir, mkdir, and rmdir requests.  }
  213.   { requires xxpatherr and current drive, above.}
  214. var w   : pathtype;
  215.     reg :regtype;      {note earlier change in rtype name}
  216. begin
  217.   w := x + chr(0);
  218.   if w[2] <> ':' then   {add drive designator}
  219.     w := currentdrive + w;
  220.   reg.ax := k;
  221.   reg.ds := seg(w[1]);
  222.   reg.dx := ofs(w[1]);
  223.   intr($21,reg);
  224.   if (reg.flags and 1) > 0 then xxpatherr(x);
  225. end;
  226.  
  227. procedure chdir(x:pathtype);
  228.   {  equivalent to chdir command in dos.              }
  229.   { requires xxdir, xxpatherr, and currentdrive, above}
  230.   { caution!  do not leave a directory                }
  231.   { if you have files in it open                      }
  232. begin
  233.   xxdir(x,$3B00);
  234. end;
  235.  
  236.  
  237. procedure rmdir(x:pathtype);
  238.   { equivalen to rmdir command in DOS.                }
  239.   { requires xxdir, xxpatherr, and currentdrive, above}
  240. begin
  241.   xxdir(x,$3a00);
  242. end;
  243.  
  244. procedure mkdir(x:pathtype);
  245.   {  equivalen to mkdir command in DOS                }
  246.   { requires xxdir, xxpatherr, and currentdrive, above}
  247. begin
  248.   xxdir(x,$3900);
  249. end;
  250.  
  251. procedure rename(x,y:pathtype);
  252.   { renames a file; unlike thd DOS rename command     }
  253.   { both parameters of this command are full paths.   }
  254.   { the paths need not be the same, allowing a file   }
  255.   { to be moved from one directory to another.        }
  256.   { first parameter can specify a drive; any drive    }
  257.   { letter on the second parameter is ignored.        }
  258. var wx,wy : pathtype;
  259.     reg   : regtype;      {note earlier change in rtype name}
  260. begin
  261.   wx := x + chr(0);
  262.   wy := y + chr(0);
  263.   if wx[2] <> ':' then wx := currentdrive + wx;
  264.   reg.ax := $5600;
  265.   reg.ds := seg(wx[1]);
  266.   reg.dx := ofs(wx[1]);
  267.   reg.es := seg(wy[1]);
  268.   reg.di := ofs(wy[1]);
  269.   intr($21,reg);
  270.   if (reg.flags and 1) <> 0 then
  271.     begin
  272.       writeln('Error -- invalid rename request');
  273.       writeln('      -- from: ''',x,'''');
  274.       writeln('      -- to:   ''',y,'''');
  275.       halt;
  276.     end;
  277. end;
  278.  
  279. (*************************************************************************)
  280.  
  281. { Turbo Pascal removeable window system }
  282. { copyright 1984 Michael A. Covington }
  283.  
  284. { requirements: IBM PC or close compatable      }
  285. { screen must be in text move, on page 1        }
  286. { either mon or color card                      }
  287.  
  288. { CALL INITWIN BEFOR CALLING MKWIN OR RMWIN!    }
  289.  
  290. const maxwin = 5;  {maximum number of windows open at onece }
  291.  
  292. type imagetype = array[1..4096] of char;
  293.      windimtype = record
  294.                     x1,y1,x2,y2 : integer;
  295.                   end;
  296. var win : record    {global variable package}
  297.             dim   : windimtype;      {current windor dimensions}
  298.             depth : integer;
  299.             stack : array[1..maxwin] of record
  300.                                image : imagetype;  {saved screen image}
  301.                                dim   : windimtype; {saved window dimensions}
  302.                                x,y   : integer     {saved cursor position}
  303.                              end;
  304.           end;
  305.     crtmode       : byte      absolute $0040:$0049;
  306.     crtwidth      : byte      absolute $0040:$004A;
  307.     monobuffer    : imagetype absolute $B000:$0000;
  308.     colorbuffer   : imagetype absolute $b800:$0000;
  309.  
  310. procedure initwin;
  311.   { records initial window dimension }
  312. begin
  313.   with win.dim do
  314.     begin x1:= 1; y1:= 1; x2:=crtwidth; y2:= 25; end;
  315.   win.depth := 0;
  316. end;
  317.  
  318. procedure boxwin(x1,y1,x2,y2:integer);
  319.   { draws a box, fills it with blanks, and makes it the current }
  320.   { window.  Dimensions give are for the bos; actual windos is  }
  321.   { one unit smaller in each direction.                         }
  322.   { This routine can be used separately from the rest of the    }
  323.   { removable window package.                                   }
  324. var x,y : integer;
  325. begin
  326.   window(1,1,80,25);
  327.   { TOP }
  328.   gotoxy(x1,y1);
  329.   write(chr(213));
  330.   for x := x1 +1 to x2-1 do write(chr(205));
  331.   write(chr(184));
  332.   { SIDES }
  333.   for y := y1+1  to y2-1 do
  334.     begin
  335.       gotoxy(x1,y);
  336.       write(chr(179),' ':x2-x1-1,chr(179));
  337.     end;
  338.   { BOTTOM }
  339.   gotoxy(x1,y2);
  340.   write(chr(212));
  341.   for x := x1+1 to x2-1 do write(chr(205));
  342.   write(chr(190));
  343.   { make it the current window }
  344.   window(x1+1,y1+1,x2-1,y2-1);
  345.   gotoxy(1,1);
  346. end;
  347.  
  348. procedure mkwin(x1,y1,x2,y2:integer);
  349.   { create a remiveable window }
  350. begin
  351.   {increment stack pointer }
  352.   with win do depth := depth + 1;
  353.   if win.depth > maxwin then
  354.     begin
  355.       writeln('','Window nested too deep ');
  356.       halt;
  357.     end;
  358.   { save contents of screen }
  359.   if crtmode = 7 then
  360.     win.stack[win.depth].image := monobuffer
  361.   else
  362.     win.stack[win.depth].image := colorbuffer;
  363.   win.stack[win.depth].dim := win.dim;
  364.   win.stack[win.depth].x   := wherex;
  365.   win.stack[win.depth].y   := wherey;
  366.   { create the window }
  367.   boxwin(x1,y1,x2,y2);
  368.   win.dim.x1 := x1 + 1;
  369.   win.dim.y1 := y1 + 1;  { allow for margins }
  370.   win.dim.x2 := x2 - 1;
  371.   win.dim.y2 := y2 - 1;
  372. end;
  373.  
  374. procedure rmwin;
  375.   { remove the most recently created removable window }
  376.   { restore screen contents, window dimensions, and   }
  377.   { position of cursor.                               }
  378. begin
  379.   if crtmode = 7 then
  380.     monobuffer  := win.stack[win.depth].image
  381.   else
  382.     colorbuffer := win.stack[win.depth].image;
  383.   with win do
  384.     begin
  385.       dim := stack[depth].dim;
  386.       window(dim.x1,dim.y1,dim.x2,dim.y2);
  387.       gotoxy(stack[depth].x,stack[depth].y);
  388.       depth := depth - 1;
  389.     end;
  390. end;